package com.bestillet.defaultmultishop;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.AsyncTask.Status;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MixActivity extends Activity {
	private ArrayList<Mix> mix;

	private SwipeRefreshLayout swipe;
	private DrawerLayout layout;
	private ProgressBar loading;
	private ListView sidemenu, list;
	private TextView name, price, description;
	private Button add, back, home, basket, settings;
	private Context context;
	
	private MixArrayAdapter adapter;
	private ShopApplication app;
	private CommentDialog c;
	private DeselectDialog d;
	private OptionDialog o;
	private CheckDialog m;
	private MixDialog dialog;
	private MixTask mTask;
	private AddTask aTask;
	private Menu menu;
	
	private String[] items;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_mix);
		
		context = this;
		app = (ShopApplication) getApplicationContext();
		menu = getIntent().getParcelableExtra("menu");

		items = new String[3 + app.getCards().size()];
		for (int i = 0; i < 3 + app.getCards().size(); i++) {
			switch (i) {
			case 0:
				items[i] = "Info";
				break;
			case 1:
				items[i] = "Indstillinger";
				break;
			case 2:
				items[i] = "Genbestil ordre";
				break;
			default:
				items[i] = app.getCards().get(i - 3).getName();
				break;
			}
		}
		
		loading = (ProgressBar) findViewById(R.id.progressBar1);
		
		layout = (DrawerLayout) findViewById(R.id.drawer_layout);
        sidemenu = (ListView) findViewById(R.id.left_drawer);
        
        sidemenu.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, items));
        sidemenu.setOnItemClickListener(new DrawerItemClickListener());

		name = (TextView) findViewById(R.id.lblAddName);
		price = (TextView) findViewById(R.id.lblAddPrice);
		description = (TextView) findViewById(R.id.lblAddDescription);
		
        swipe = (SwipeRefreshLayout) findViewById(R.id.swipe);
		swipe.setProgressViewOffset(false, 0, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
        swipe.setOnRefreshListener(new OnRefreshListener() {
			@Override
			public void onRefresh() {
				mTask = new MixTask();
				mTask.execute();
			}
		});
		
		name.setText(menu.getName().replace("\\n", " "));
		price.setText(menu.getPrice() + menu.getNrtxt());
		description.setText("");
		//description.setText(Html.fromHtml(menu.getExtra().replace("\\n", "<br>")));

		add = (Button) findViewById(R.id.btnAdd);
		add.setEnabled(false);
		add.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				ArrayList<String> missing = new ArrayList<String>();
				int amount = Integer.parseInt(mix.get(1).getChoice().getName());
				int extra = 0;
				for (int i = 0; i < mix.size(); i++)
					if (mix.get(i).getExtra() > 0)
						extra += mix.get(i).getExtra() * Integer.parseInt(mix.get(i).getChoice().getName());
				
				Item item = new Item(menu, amount);
				for (int i = 2; i < mix.size(); i++) {
					if (mix.get(i) instanceof MixHeader) {
						MixHeader header = (MixHeader) mix.get(i);
						for (int j = 0; j < header.getMix().size(); j++)
							if (!header.getMix().get(j).getChoice().isSelectable())
								missing.add(header.getMix().get(j).getName());
						item.addHeader(header);
					}
					else if (mix.get(i) instanceof MixGroup) {
						MixGroup g = (MixGroup) mix.get(i);
						int antal = Integer.parseInt(mix.get(1).getChoice().getName()) * (g.getAmount() + extra);
						int valgt = 0;
						
						for (int j = 0; j < g.getMix().size(); j++) {
							valgt += Integer.parseInt(g.getMix().get(j).getChoice().getName());
						}
						
						if (antal != valgt)
							missing.add(g.getName());
						item.addGroup(g);
					} else {
						if (mix.get(i).getType() == 1 && !mix.get(i).isHeader())
							if (!mix.get(i).getChoice().isSelectable())
								missing.add(mix.get(i).getName());
						item.addMix(mix.get(i));
					}
				}
				
				if (missing.size() > 0) {
					String s = "";
					for (int i = 0; i < missing.size(); i++) {
						if (i == missing.size() - 1 && i > 0)
							s += " og ";
						else if (i > 0)
							s += ", ";
						s += missing.get(i);
					}
					dialog = new MixDialog(v.getContext(), s);
					dialog.show();
				} else {
					for (MixHeader h : item.getHeaders()) {
						for (Mix m : h.getMix())
							item.getMix().remove(m);
						item.getMix().remove(h);
					}
					for (MixGroup g : item.getGroups()) {
						for (Mix m : g.getMix())
							item.getMix().remove(m);
						item.getMix().remove(g);
					}
					
	    			add.setVisibility(View.GONE);
	    			loading.setVisibility(View.VISIBLE);
					aTask = new AddTask();
					aTask.execute(item);
				}
			}
		});
		
		back = (Button) findViewById(R.id.btnAddBack);
		back.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		
		home = (Button) findViewById(R.id.btnAddHome);
		home.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), CampaignActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				startActivity(intent);
			}
		});
		
		basket = (Button) findViewById(R.id.btnAddBasket);
		basket.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), BasketActivity.class);
				startActivity(intent);
			}
		});
		
		settings = (Button) findViewById(R.id.btnSettings);
		settings.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				layout.openDrawer(sidemenu);
			}
		});

		list = (ListView) findViewById(android.R.id.list);
		list.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
				switch (mix.get(position).getType()) {
				case 1:
					o = new OptionDialog(v.getContext(), mix.get(position));
					o.show();
					break;
				case 2:
					m = new CheckDialog(v.getContext(), position, mix.get(position));
					m.show();
					break;
				case 3:
					d = new DeselectDialog(v.getContext(), mix.get(position));
					d.show();
					break;
				case 4:
					c = new CommentDialog(v.getContext(), mix.get(position));
					c.show();
					break;
				default:
					o = new OptionDialog(v.getContext(), mix.get(position));
					o.show();
					break;
				}
			}
		});
		
		swipe.setRefreshing(true);
		mTask = new MixTask();
		mTask.execute();
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		if (aTask != null)
			if (aTask.getStatus() == Status.RUNNING)
				aTask.cancel(true);
		
		if (mTask != null)
			if (mTask.getStatus() == Status.RUNNING)
				mTask.cancel(true);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		Calendar date = Calendar.getInstance();
		Calendar deadline = app.getShop().getDeadline();
		if (date.get(Calendar.YEAR) != deadline.get(Calendar.YEAR) || date.get(Calendar.MONTH) != deadline.get(Calendar.MONTH) || date.get(Calendar.DAY_OF_MONTH) != deadline.get(Calendar.DAY_OF_MONTH)) {
			Intent intent = new Intent(this, ShopActivity.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
		}
	}
	
	public void updateChoices() {
		getPrice();
		adapter.notifyDataSetChanged();
	}
	
	public void getPrice() {
		int amount = Integer.parseInt(mix.get(1).getChoice().getName());
		int result = menu.getPrice();
		
		for (int i = 1; i < mix.size(); i++) {
			Mix m = mix.get(i);
			if (!m.isHeader()) {
				switch (m.getType()) {
				case 1:
					result += m.getChoice().getPrice();
					break;
				case 2:
					for (int j = 0; j < m.getChoices().size(); j++)
						result += m.getChoices().get(j).getPrice();
					break;
				case 3:
					
					break;
				default:
					result += m.getChoice().getPrice();
					break;
				}
			}
		}
		
		price.setText((result * amount) + ",-");
	}
	
	private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {
    	switch (position) {
		case 0:
			Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(Server.INFO + app.getShop().getIdx()));
			startActivity(browserIntent);
			break;
		case 1:
			Intent customer = new Intent(this, CustomerActivity.class);
			startActivity(customer);
			break;
		case 2:
			Intent order = new Intent(this, OrderActivity.class);
			startActivity(order);
			break;
		default:
			Intent card = new Intent(this, CardActivity.class);
			card.putExtra("index", position - 3);
			startActivity(card);
			break;
		}
    	
        sidemenu.setItemChecked(position, false);
        layout.closeDrawer(sidemenu);
    }
	
	private void setListHeight() {
		int height = 0;
		
		for (int i = 0; i < adapter.getCount(); i++) {
			View v = adapter.getView(i, null, list);
			v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
			height += v.getMeasuredHeight();
		}
		
		ViewGroup.LayoutParams params = list.getLayoutParams();
		params.height = height + (list.getDividerHeight() * (adapter.getCount() - 1));
		list.setLayoutParams(params);
		list.requestLayout();
	}
	
	private class MixTask extends AsyncTask<Void, Void, Boolean> {
    	@Override
		protected Boolean doInBackground(Void... params) {
    		try {
    			InputStream in = Server.post(Server.MIX, Server.getAuthenticationMix(app.getShop().getIdx(), menu.getIdx()));
    			XmlPullParser parser = Server.toXmlParser(in);
    			mix = XmlParser.getMix(parser);
    			mix.add(0, new Mix("valg", "Valg", true, -1, 1, 0));
    			mix.add(1, getAntal());
    			in.close();
    		} catch (IOException e) {
    			Log.e("Shop", "IOException: " + e.getMessage());
    			return false;
    		} catch (XmlPullParserException e) {
    			Log.e("Shop", "XmlPullParserException: " + e.getMessage());
    			return false;
    		} catch (NullPointerException e) {
    			Log.e("Shop", "NullPointerException: " + e.getMessage());
    			return false;
    		} catch (IllegalArgumentException e) {
    			Log.e("Shop", "IllegalArgumentException: " + e.getMessage());
    			return false;
    		}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
			swipe.setRefreshing(false);
	    	if (success) {
    			adapter = new MixArrayAdapter(context, mix);
				list.setAdapter(adapter);
				setListHeight();
    			add.setEnabled(true);
    			getPrice();
	    	} else {
	    		AlertDialog.Builder builder = new AlertDialog.Builder(context);
	    		builder.setMessage(R.string.error_mix)
	    		       .setTitle(R.string.error)
	    		       .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								swipe.setRefreshing(true);
								mTask = new MixTask();
								mTask.execute();
							}
						})
						.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								finish();
							}
						});
	    		AlertDialog dialog = builder.create();
	    		dialog.show();
	    	}
	    }
		
		private Mix getAntal() {
			Mix m = new Mix("antal", "Antal", false, -1, 1, 0);
			for (int i = menu.getMinAntal(); i < menu.getMaxAntal() + 1; i++)
				m.addOption(new Option("" + i, true, -1, 0));
			m.setChoice(m.getOptions().get(0));
			return m;
		}
	}
	
	private class AddTask extends AsyncTask<Item, Void, Boolean> {
		private Item item;
		
		@Override
		protected Boolean doInBackground(Item... params) {
    		try {
    			item = params[0];
    			InputStream in = Server.post(Server.ADD, Server.getBasketItemXml(app.getShop().getIdx(), app.getBasketId(), item));
    			XmlPullParser parser = Server.toXmlParser(in);
    			int itemId = XmlParser.getItemId(parser);
    			in.close();
    			return itemId != -1;
			} catch (IOException e) {
    			Log.e("Shop", "IOException: " + e.getMessage());
				return false;
			} catch (NullPointerException e) {
    			Log.e("Shop", "NullPointerException: " + e.getMessage());
				return false;
			} catch (XmlPullParserException e) {
				Log.e("Shop", "XmlPullParserException: " + e.getMessage());
				return false;
			} catch (IllegalArgumentException e) {
				Log.e("Shop", "IllegalArgumentException: " + e.getMessage());
				return false;
			}
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
	    	if (success) {
	    		Intent intent = new Intent(context, BasketActivity.class);
				startActivity(intent);
	    	} else {
	    		AlertDialog.Builder builder = new AlertDialog.Builder(context);
	    		builder.setMessage(R.string.error_add)
	    		       .setTitle(R.string.error)
	    		       .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
				    			add.setVisibility(View.GONE);
				    			loading.setVisibility(View.VISIBLE);
								aTask = new AddTask();
								aTask.execute(item);
							}
						})
						.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) { }
						});
	    		AlertDialog dialog = builder.create();
	    		dialog.show();
	    	}
			add.setVisibility(View.VISIBLE);
			loading.setVisibility(View.GONE);
	    }
    }
}